﻿//===============================================================================
// PostSharp Poco implementation for EntityFramework
//===============================================================================
// Copyright © Ruurd Boeke.  All rights reserved.
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY
// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT
// LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS FOR A PARTICULAR PURPOSE.
//===============================================================================
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using PostSharp.Laos;
using System.ComponentModel;
using EntityFrameworkContrib.PostSharp4EF;

namespace EditableBusinessObjects.Postsharp.Public
{
    public interface IFirePropertyChanged
    {
        void OnPropertyChanged(string propertyName);
    } 

    /// <summary>
    /// Implementation of <see cref="CompositionAspect"/> that adds the <see cref="INotifyPropertyChanged"/>
    /// interface to the type to which it is applied.
    /// </summary>
    [Serializable]
    class AddNotifyPropertyChangedInterfaceSubAspect : CompositionAspect
    {
        /// <summary>
        /// Called at runtime, creates the implementation of the <see cref="INotifyPropertyChanged"/> interface.
        /// </summary>
        /// <param name="eventArgs">Execution context.</param>
        /// <returns>A new instance of <see cref="NotifyPropertyChangedImplementation"/>, which implements
        /// <see cref="INotifyPropertyChanged"/>.</returns>
        public override object CreateImplementationObject(InstanceBoundLaosEventArgs eventArgs)
        {
            return new NotifyPropertyChangedImplementation(eventArgs.Instance);
        }

        /// <summary>
        /// Called at compile-time, gets the interface that should be publicly exposed.
        /// </summary>
        /// <param name="containerType">Type on which the interface will be implemented.</param>
        /// <returns></returns>
        public override Type GetPublicInterface(Type containerType)
        {
            return typeof(INotifyPropertyChanged);
        }

        public override Type[] GetProtectedInterfaces(Type containerType)
        {
            return new Type[] { typeof(IFirePropertyChanged) };
        }

        /// <summary>
        /// Gets weaving options.
        /// </summary>
        /// <returns>Weaving options specifying that the implementation accessor interface (<see cref="IComposed{T}"/>)
        /// should be exposed, and that the implementation of interfaces should be silently ignored if they are
        /// already implemented in the parent types.</returns>
        public override CompositionAspectOptions GetOptions()
        {
            return
                CompositionAspectOptions.GenerateImplementationAccessor |
                CompositionAspectOptions.IgnoreIfAlreadyImplemented;
        }

    }
}
